package com.example.layui_project.comm.config;
import com.example.layui_project.comm.filter.RoleFilter;
import com.example.layui_project.entity.SysPermission;
import com.example.layui_project.entity.SysRole;
import com.example.layui_project.service.PermissionService;
import com.example.layui_project.service.RoleService;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Autowired
    private UserRealm userRealm;
    @Autowired
    private RoleService roleService;
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 存放自定义的filter，这里导入的是：javax.servlet.Filter
        LinkedHashMap<String, Filter> filtersMap = new LinkedHashMap<>();
        // 配置自定义 or角色 认证
        filtersMap.put("roles", new RoleFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);
        /**
         * 当你没有在realm里面写入登录的验证代码的话，页面就算输入正确的用户名密码还是登录不进去
         */
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setSuccessUrl("/index/toIndex.do");
        // 这里是权限不足跳转页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/error.html");
        /**
         * shiro的内置过滤器
         anon：无需认证就可以访问 默认
         authc：必须认证了才能访问（表单认证）
         user：必须拥有记住我功能才能访问
         perms：必须拥有对某个的权限才能访问
         role：拥有某个角色权限才能访问
         */
        //添加shiro的内置过滤器  设置要拦截的url
        Map<String,String> filterChainDefinitionMap=new LinkedHashMap<>();//拦截
        /**
         * 这是获取图片验证码地址，是用于登录的所以该链接无需认证
         */
        filterChainDefinitionMap.put("/login/defaultKaptcha.do","anon");
        filterChainDefinitionMap.put("/login/startLogin.do","anon");

        // 代表要访问这些链接必须具有admin这个权限才能访问
        /*List<SysRole> roleAndPermissionByMenu = roleService.getRoleAndPermissionByMenu();
        roleAndPermissionByMenu.forEach((t)->{
            List<SysPermission> sysPermissionList = t.getSysPermissionList();
            sysPermissionList.forEach((s)->{
                // 这里如果一个连接可以同时适用于两个角色，所以需要先get一次判断有没有，有就修改
                filterChainDefinitionMap.compute(s.getHref(), (k,v)-> {
                    System.out.println("key = " + k + ", value = " + v);
                    if (v != null) {
                        String c = v.substring(0, v.lastIndexOf("]"));
                        String str = c + ","+ t.getRolename() + "]";
                        return str;
                    } else {
                        return "roles["+t.getRolename()+"]";
                    }
                });
            });
        });*/
        System.out.println("最终角色结果是："+filterChainDefinitionMap.toString());
        /*filterChainDefinitionMap.put("/role/toRoleList.do","roles[超级管理员,访客]");*/
        /*filterChainDefinitionMap.put("/role/findData.do","roles[comm]");
        filterChainDefinitionMap.put("/role/add.do","roles[comm]");
        filterChainDefinitionMap.put("/role/update.do","roles[comm]");
        filterChainDefinitionMap.put("/role/del.do","roles[comm]");*/
       /* HashMap<String, Filter> filterHashMap = new HashMap<>();
        filterHashMap.put("roles",new ShiroRolesFilter());
        shiroFilterFactoryBean.setFilters(filterHashMap);*/
        /**
         * 若是直接访问的未授权页面那么会直接返回到登录页面
         */
        //<!-- 过滤链定义，从上向下顺序执行，一般将 /**放在最为下边 -->:这是一个坑呢，一不小心代码就不好使了;
        filterChainDefinitionMap.put("/*/*.do","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(userRealm);
        return defaultWebSecurityManager;
    }
}
